package utils

import (
	"alertmanagerWebhook/core"
	"alertmanagerWebhook/global"
	"fmt"

	"github.com/gomodule/redigo/redis"
)

type RedisUtil struct {
	conn redis.Conn
}

func NewRedisUtil() (*RedisUtil, error) {
	conn, err := core.ConnRedis()
	if err != nil {
		return nil, fmt.Errorf("redis connection failed: %w", err)
	}
	return &RedisUtil{conn: conn}, nil
}

func (r *RedisUtil) Close() {
	if r.conn != nil {
		r.conn.Close()
	}
}

// func (r *RedisUtil) HSet(key, field string, value interface{}) error {
// 	conn, err := core.GetWritableRedisConn()
// 	if err != nil {
// 		return fmt.Errorf("获取可写连接失败: %w", err)
// 	}
// 	defer conn.Close()

// 	_, err = conn.Do("HSet", key, field, value)
// 	return err
// }

// 修改HGet方法，根据模式自动选择连接
func (r *RedisUtil) HGet(key, field string) (string, error) {
	if global.Config.Redis.Mode == "master-slave" {
		return HGetReadable(key, field)
	}
	conn, err := core.GetWritableRedisConn()
	if err != nil {
		return "", fmt.Errorf("获取连接失败: %w", err)
	}
	defer conn.Close()
	return redis.String(conn.Do("HGET", key, field))
}

// 修改HSet方法，根据模式自动选择连接
func (r *RedisUtil) HSet(key, field string, value interface{}) error {
	if global.Config.Redis.Mode == "master-slave" {
		return HSetWritable(key, field, value)
	}
	conn, err := core.GetWritableRedisConn()
	if err != nil {
		return fmt.Errorf("获取连接失败: %w", err)
	}
	defer conn.Close()
	_, err = conn.Do("HSET", key, field, value)
	return err
}

func (r *RedisUtil) HIncrBy(key, field string, increment int) error {
	if global.Config.Redis.Mode == "master-slave" {
		return HIncrByWritable(key, field, increment)
	}
	conn, err := core.GetWritableRedisConn()
	if err != nil {
		return fmt.Errorf("获取可写连接失败: %w", err)
	}
	defer conn.Close()
	_, err = conn.Do("HIncrBy", key, field, increment)
	return err
}

func (r *RedisUtil) HDel(key, field string) error {
	if global.Config.Redis.Mode == "master-slave" {
		return HDelWritable(key, field)
	}
	conn, err := core.GetWritableRedisConn()
	if err != nil {
		return fmt.Errorf("获取可写连接失败: %w", err)
	}
	defer conn.Close()
	_, err = conn.Do("HDel", key, field)
	return err
}

func (r *RedisUtil) HGetInt(key, field string) (int, error) {
	if global.Config.Redis.Mode == "master-slave" {
		return HGetIntReadable(key, field)
	}
	conn, err := core.GetReadOnlyRedisConn()
	if err != nil {
		return 0, fmt.Errorf("获取只读连接失败: %w", err)
	}
	defer conn.Close()
	count, err := redis.Int(r.conn.Do("HGet", key, field))
	if err != nil {
		return 0, fmt.Errorf("failed to get int from redis: %w", err)
	}
	return count, nil
}

func (r *RedisUtil) Expire(key string, seconds int) error {
	if global.Config.Redis.Mode == "master-slave" {
		return ExpireWritable(key, seconds)
	}
	conn, err := core.GetWritableRedisConn()
	if err != nil {
		return fmt.Errorf("获取可写连接失败: %w", err)
	}
	defer conn.Close()
	_, err = conn.Do("EXPIRE", key, seconds)
	return err
}

// 主从架构下的写操作
func HSetWritable(key, field string, value interface{}) error {
	if global.Config.Redis.Mode != "master-slave" {
		return fmt.Errorf("HSetWritable only for master-slave mode")
	}
	conn, err := core.GetWritableRedisConn()
	if err != nil {
		return err
	}
	defer conn.Close()
	_, err = conn.Do("HSET", key, field, value)
	return err
}

// 主从架构下的读操作
func HGetReadable(key, field string) (string, error) {
	if global.Config.Redis.Mode != "master-slave" {
		return "", fmt.Errorf("HGetReadable only for master-slave mode")
	}
	conn, err := core.GetReadOnlyRedisConn()
	if err != nil {
		return "", err
	}
	defer conn.Close()
	return redis.String(conn.Do("HGET", key, field))
}

// 主从架构下的整型读操作
func HGetIntReadable(key, field string) (int, error) {
	if global.Config.Redis.Mode != "master-slave" {
		return 0, fmt.Errorf("HGetIntReadable only for master-slave mode")
	}
	conn, err := core.GetReadOnlyRedisConn()
	if err != nil {
		return 0, err
	}
	defer conn.Close()
	return redis.Int(conn.Do("HGET", key, field))
}

// 主从架构下的删除操作
func HDelWritable(key, field string) error {
	if global.Config.Redis.Mode != "master-slave" {
		return fmt.Errorf("HDelWritable only for master-slave mode")
	}
	conn, err := core.GetWritableRedisConn()
	if err != nil {
		return err
	}
	defer conn.Close()
	_, err = conn.Do("HDEL", key, field)
	return err
}

// 主从架构下的自增操作
func HIncrByWritable(key, field string, increment int) error {
	if global.Config.Redis.Mode != "master-slave" {
		return fmt.Errorf("HIncrByWritable only for master-slave mode")
	}
	conn, err := core.GetWritableRedisConn()
	if err != nil {
		return err
	}
	defer conn.Close()
	_, err = conn.Do("HINCRBY", key, field, increment)
	return err
}

// 主从架构下的设置过期时间操作
func ExpireWritable(key string, seconds int) error {
	if global.Config.Redis.Mode != "master-slave" {
		return fmt.Errorf("ExpireWritable only for master-slave mode")
	}
	conn, err := core.GetWritableRedisConn()
	if err != nil {
		return err
	}
	defer conn.Close()
	_, err = conn.Do("EXPIRE", key, seconds)
	return err
}
